<?

function dump($input,$key="...")
{
	$dump=new dump($input,$key);
	$dump->print_styled();
} 
/**
* Common Class to Dump data in an comprehensible fashion
*/
class dump
{
	var $template=array(
'ul'=>'
	<ul{class:ul}>
		{value:ul}
	</ul>',
'li'=>'
	<li{class:li}>
		<a onClick="dumpToggle(this)" title="{value:title}">
			{value:a}
		</a>
		{sub}
	</li>',
'value'=>'
	<span title="{title}"><strong>{key}</strong> <em>({info})</em> <var>{value}</var></span>',
'table'=>'
	<div class="overflow">
		<table cellspacing="0px" cellpadding="0">
			{value:table}
		</table>
	</div>',
'table:head:item'=>
	'<th {config:th}>
		{value:th}
	</th>',
'table:item'=>
	'<td {config:td}>
		{value:td}
	</td>',
'table:row:even'=>
	'<tr class="even" {config:tr}>
		{value:tr}
	</tr>',
'table:row:odd'=>
	'<tr class="odd" {config:tr}>
		{value:tr}
	</tr>');

	var $StyleAndJS='
<script type="text/javascript" charset="utf-8">
    function dumpToggle(element) {
       var e = element.parentNode.getElementsByTagName("ul")[0];
       if(e!=null){
	       if(e.style.display == "block")
	          e.style.display = "none";
	       else
	          e.style.display = "block";
	    }
    }
</script>
<style type="text/css" media="screen">
	ul.dump li{
		color:#113C64;
	}
	ul.dump a{
		display:block;
		width:100%;
	}
	ul.dump li,
	ul.dump ul{
		list-style:none;
		margin:0px;
	}
	ul.dump li.hasSub{
		cursor:pointer;
		list-style:square;
	}
	ul.dump a:hover{
		background:#9ABBC7;
	}
	ul.dump ul{
		display:none;
		padding-left:22px;
		border-left: 1px dotted  #304860;
	}
	ul.dump{
		padding:2px;
		padding-left:22px;
		color:#1D2327;
		font-family:tahoma,Verdana;
		font-size:12px;
		display:block;
		border:1px #304860 solid;
	}
	ul.dump span.value{
		color:#113C64;
	}
	ul.dump em{
		font-style:normal;
	}
	ul.dump var{
		font-style:normal;
		font-weight:bold;
	}
	ul.dump var{
		font-style:normal;
		font-weight:bold;
	}
	ul.array{
		background:#EEFF96;
		background:#E1FF4B;
	}
	ul.object{
		background:#DDDFFA;
	}
	ul.resource{
		background:#FFC4C3;
	}
	table{
		font-size:11px;
	}
	td{
		padding:2px;
		margin:0px;
	}
	th{
		padding:2px;
	}
	div.overflow{
		max-height:500px;
		overflow:auto;
	}
	ul.resource:hover,
	div.overflow:hover,
	table:hover
	{
		background:#FFC4C3;
	}
	tr.even td{
		background:#FFD4C3;
	}
	tr:hover td{
		background:#9ABBC7;
	}
	th{
		background:#eFa4a3;
	}
</style>';

	public function StyleAndJS()
	{
		$this->return.=$this->StyleAndJS;
		define("dumpStyleAndJS",true);
	}
	
	public function dump($input,$key)
	{
		if(!defined("dumpStyleAndJS")){
			$this->StyleAndJS();
		}
		$this->return.=$this->iterate($input,$key);
	}
	
	public function iterate($inputValue,$inputKey)
	{
		if(empty($this->first)){
			$first=true;
			$this->first=1;
		}else{
			$first=false;
		}
		switch (!$first) {
			case FALSE:
				$first=false;
				$param=array(
					"class:ul"=>" class='dump ".gettype($inputValue)."'",
					"value:ul"=>$this->iterate($inputValue,$inputKey)
				);
				
				return $this->parse("ul",$param);
				break;
				
			case is_Array($inputValue):
				foreach ($inputValue as $key => $value) {
					/*$param["class:li"]=(is_array($value)||is_resource($value)||is_object($value)) ? " class='hasSub'" : "";
					$param["value:a"]=$this->getInfo($value,$key);
					$param["value:title"]=gettype($value);
					$param["sub"]=$this->iterate($value);
					$return.= $this->parse("li",$param);*/
					$return.=$this->iterate($value,$key);
				}
				
				$param=array(
					"class:ul"=>" class='array'",
					"value:ul"=>$return
				);
				$return = $this->parse("ul",$param);
				
				
				$param["class:li"]=" class='hasSub'";
				$param["value:a"]=$this->getInfo($inputValue,$inputKey);
				$param["value:title"]=gettype($inputValue);
				$param["sub"]=$return;
				
				return $this->parse("li",$param);
				break;
			
			case is_Object($inputValue):
				$array=get_object_vars($inputValue);
				
				foreach ($array as $key => $value) {
					$return.=$this->iterate($value,$key);
				}
				
				$param=array(
					"class:ul"=>" class='object'",
					"value:ul"=>$return
				);
				$return = $this->parse("ul",$param);
				
				
				$param["class:li"]=" class='hasSub'";
				$param["value:a"]=$this->getInfo($inputValue,$inputKey);
				$param["value:title"]=gettype($inputValue);
				$param["sub"]=$return;
				
				return $this->parse("li",$param);
				break;
				
			case is_Resource($inputValue):
				
				$param["value:a"]=$this->parseTable($inputValue);
				$param["value:title"]=gettype($inputValue);
				$return = $this->parse("li",$param);
				
				
				$param=array(
					"class:ul"=>" class='resource'",
					"value:ul"=>$return
				);
				$return = $this->parse("ul",$param);
				
				$param["class:li"]=" class='hasSub'";
				$param["value:a"]=$this->getInfo($inputValue,$inputKey);
				$param["value:title"]=gettype($inputValue);
				$param["sub"]=$return;
				
				return $this->parse("li",$param);
				break;
				
			default:
				$param["value:a"]=$this->getInfo($inputValue,$inputKey);
				$param["value:title"]=gettype($inputValue);
				
				return $this->parse("li",$param);
				break;
		}
	}
	
	public function getInfo($input,$key)
	{
		switch (TRUE) {
			case is_array($input):
				$param["key"]=$key;
				$param["type"]=$key;
				$param["title"]="(".gettype($input).", ".strlen($input)." elements)";
				$param["info"]=gettype($input).", ".strlen($input)." elements";
				$param["value"]=$input;
				break;
				
			case is_object($input):
				$param["key"]=$key;
				$param["type"]=$key;
				$param["title"]=gettype($input);
				$param["info"]=gettype($input);
				$param["value"]=get_class($input);
				break;
			
			case 'string':
				$param["type"]=$key;
				$param["key"]=$key;
				$param["title"]="(".gettype($input).", ".strlen($input)." chars)";
				$param["info"]=gettype($input).", ".strlen($input)." chars";
				$param["value"]=$input;
				break;
				
			default:
				$param["type"]=$key;
				$param["key"]=$key;
				$param["title"]="(".gettype($input).", ".strlen($input)." elements)";
				$param["info"]=gettype($input).", ".strlen($input)." elements";
				$param["value"]=$input;
				break;
		}
		return $this->parse("value",$param);
	}
	
	public function parse($element,$param)
	{
		$element=$this->template[$element];
		foreach ($param as $key => $value) {
			$key=$key ? $key : gettype($key);
			$element=str_replace("{".$key."}",$value,$element);
		}
		$element=$this->cleanup($element);
		return $element;
	}
	
	public function parseTable($inputValue)
	{
		$head=true;
		$count=0;
		while($array=mysql_fetch_assoc($inputValue)){
			#$return.=$this->iterate($array,$count);
			
			$row="";
			$param="";
			$param["value:th"]=$count++;
			$row.=$this->parse("table:head:item",$param);
			
			if($head){
				$head=false;
				$param="";
				$param["value:th"]="";
				$headRow.=$this->parse("table:head:item",$param);
				foreach ($array as $key => $value) {
					$param="";
					$param["value:th"]=$key;
					$headRow.=$this->parse("table:head:item",$param);
				}
				$param="";
				$param["value:tr"]=$headRow;
				$return.=$this->parse("table:row:even",$param);
			}
			
			foreach ($array as $key => $value) {
				$param="";
				$param["value:td"]=$value;
				$row.=$this->parse("table:item",$param);
			}
			$param="";
			$param["value:tr"]=$row;
			
			if($switch){
				$switch=false;
				$return.=$this->parse("table:row:odd",$param);
			}else{
				$switch=true;
				$return.=$this->parse("table:row:even",$param);
			}
		}
		$param=array(
			"value:table"=>$return
		);
		$return = $this->parse("table",$param);
		return $return;
	}
	
	public function cleanup($input)
	{
		return preg_replace("/\{[^}]+}/","",$input);
	}
	
	public function print_styled()
	{
		echo $this->return;
	}
}
?>